<?php
namespace Blade;

class TemplateWrapper {

	public $engine;

	public $template;

    public $_block;

	public function __construct($engine, $template)
	{
		$this->engine = $engine;

		$this->template = $template;
	}

    /**
     * 运行模板函数
     */
    public function runTemplateFunction()
    {
    	//获得本函数的参数
    	$args = func_get_args();

    	//分割出要运行的函数名和参数
    	$functionName = $args[0];
		array_shift($args);


		//如果是系统函数
    	if( function_exists($functionName) ){
			$result = call_user_func_array($functionName, $args);
    	}

    	/**
    	 * 如果方法是模板引擎定义的过滤器，则使用本引擎预定义的过滤器
    	 */
    	if( !isset($result) && method_exists(__NAMESPACE__ .'\Functions', $functionName)  ) {
 			$result = call_user_func_array([__NAMESPACE__ .'\Functions', $functionName], $args);
    	}

    	if( is_array($result) || is_object($result) ){
    		throw new \Exception("模板函数 {$functionName} 返回了数组或者对象");
    	}

    	return isset($result) ? $result : '';
    }

    /**
     * 引入子视图
     */
    public function include($name, $params=[])
    {
    	$cacheFile =  $this->engine->cache->generateKey($name);

        if( !file_exists($cacheFile) ){
            //后期判断实际模板是否存在
            throw new \Exception("子视图不存在 {$name}");
        }

    	extract($params);
    	include($cacheFile);
    }

    /**
     * 变量输出转义
     */
    public function encode($var)
    {
        return htmlentities($var, ENT_QUOTES, 'UTF-8');
    }

    /**
     * 原始表达式输出
     */
    public function original($string)
    {
        return "{{" .$string. "}}";
    }

    public function beginBlock($id)
    {
        if(ob_start()){
            $this->_block[] = trim($id, ' ');
        }
    }

    public function endBlock()
    {
        $last = array_pop($this->_block);
        $this->_block[$last] = ob_get_clean();
    }

    public function echoBlock($name)
    {
        return isset($this->_block[$name]) ? $this->_block[$name] : '';
    }

	public function render(array $params = [])
	{
        try {
            ob_start();
            ob_implicit_flush(false);

            extract($params);
            unset($params);
            require $this->template;

            return ob_get_clean();

        } catch (\Exception $e) {

        }
	}
}